cbuffer cbPerObject
{
	float4x4 WorldViewProjection;	
	float4x4 WorldView;	
	float4x4 View;	
	float4x4 InverseProjection;
}

cbuffer cbGlobal
{
	int2 gBufferSize;
	float zFar;
	float4 lightPosIntensity[500];
	float numOfLights;
}

SamplerState GBufferSampler
{
	Filter = MIN_MAG_POINT_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};

Texture2D albedoTexture;
Texture2D normalTexture;
Texture2D depthTexture;

struct App2VS
{
	float3 pos : POSITION;
	float3 col : COLOR;
	float3 normal : NORMAL;
};
struct VS2PS
{
	float4 pos : SV_Position;
	float3 viewRay : TEXCOORD0;
};
struct PS2GPU
{
	float4 value : SV_Target0;
};


void vs(App2VS IN, out VS2PS OUT)
{
	OUT.pos = float4(IN.pos, 1); //pass through for quad/etc
	//get the viewspace viewray
	float4 viewPos = mul(float4(IN.pos.xy, 1, 1), InverseProjection);
	OUT.viewRay = viewPos.xyz / viewPos.w;
}
void ps(VS2PS IN, out PS2GPU OUT)
{
	float2 uv = IN.pos / gBufferSize;

	float2 encodedNormal = normalTexture.Sample(GBufferSampler, uv).rg;
	//float3 normal = normalize(decodeNormal(encodedNormal));
	float3 normal = normalize(normalTexture.Sample(GBufferSampler, uv).rgb);
	//linear depth in 0->1 range
	float depth = depthTexture.Sample(GBufferSampler, uv).r;

	float3 albedo = albedoTexture.Sample(GBufferSampler, uv).rgb;
	
	//reconstruct world pos using depth
	float3 viewPos = IN.viewRay * depth;
	float totalRadiance = 0;
	
	for(int i = 0; i < numOfLights; i++)
	{		
		float4 light = lightPosIntensity[i];		
		float3 lightPos =  light.xyz;
		float lightIntensity = light.w;
		float lightAttenuation = min(1 / distance(lightPos, viewPos), 1) ;
		float lightFactor = saturate(lightAttenuation * lightIntensity * dot(normal, normalize(lightPos - viewPos)));
		totalRadiance += lightFactor;
	}	

	if(0)//floor(IN.pos.x / 200) % 2 == 0)
	{
		
		float4 light = lightPosIntensity[0];		
		float3 lightPos =  light.xyz;
		float lightIntensity = light.w;
		OUT.value = float4(albedo, 1);
	}
	else
	{		
		OUT.value = totalRadiance * float4(albedo, 1);
	}
}

BlendState FinalBlend
{ 
    BlendEnable[0] = True;
	SrcBlend = One;
	DestBlend = One;
	BlendOp = Add;
	SrcBlendAlpha = One;
	DestBlendAlpha = One;
	BlendOpAlpha = ADD;
};
technique10 Render
{
	pass P0
	{
		SetGeometryShader( 0 );
		SetVertexShader( CompileShader( vs_4_0, vs() ) );
		SetPixelShader( CompileShader( ps_4_0, ps() ) );
		SetBlendState(FinalBlend, float4(0,0,0,0), 0xf);
	}
}